package org.fing.edu.uy.esbadp.action.itinerary;

import java.util.logging.Level;

import org.fing.edu.uy.esbadp.assertion.AssertProperty;
import org.fing.edu.uy.esbadp.core.AdpFlowConstants;
import org.fing.edu.uy.esbadp.core.AdpFlowInterface;
import org.fing.edu.uy.esbadp.core.AdpFlowTree;
import org.fing.edu.uy.esbadp.core.entity.GenericTreeNode;
import org.fing.edu.uy.esbadp.core.historic.FlowHistoricManager;
import org.fing.edu.uy.esbadp.logger.LoggerADP;
import org.jboss.internal.soa.esb.assertion.AssertArgument;
import org.jboss.soa.esb.actions.annotation.Process;
import org.jboss.soa.esb.client.ServiceInvoker;
import org.jboss.soa.esb.message.Message;

public class ItineraryAction {
	
	private static java.util.logging.Logger logger = LoggerADP.getLogger(ItineraryAction.class.getSimpleName());

	public ItineraryAction() {
		
	}
	
	/**
	 * @param message
	 */
	@Process
	public Message process(Message message) {
		
		if(logger.isLoggable(LoggerADP.DEBUG_LEVEL)){
			logger.log(LoggerADP.DEBUG_LEVEL, "Process Action -> {0}", this.getClass().getName());
		}

		AssertArgument.isNotNull(message, "message");
		AssertProperty.isNotNull(message, AdpFlowConstants.PropertyFlowServices);
		
		
		//se obtiene tree de propiedades
		AdpFlowTree adpFlowTree = (AdpFlowTree) message.getProperties().getProperty(AdpFlowConstants.PropertyFlowServices);
		
		//invoca al siguiente servicio segun el treeFlow o retorna la respuesta
		GenericTreeNode<AdpFlowInterface> treeNode = adpFlowTree.getCurrent();
		
		//Si existe current invoco al proximo servicio
		if(treeNode != null && treeNode.getData() != null) {
			AdpFlowInterface adpService = treeNode.getData();
			String serviceCategory = adpService.getServiceCategoryName();
			String serviceName = adpService.getServiceName();
			
			ServiceInvoker service;
			try {
				//delivero mensaje async para el servicio que se encuentra apuntado el current del arbol
				service = new ServiceInvoker(serviceCategory, serviceName);
				service.deliverAsync(message);
			} catch (Exception ex) {
				logger.log(Level.SEVERE, "Exception in ItineraryAction when delivery Async Message.", ex);
			}
			return null;
		} else {//no quedan mas acciones respondo el mensaje al cliente
			
			if(adpFlowTree.isSaveHistoric()){
				//guardo el historico esto afecta la performance en caso de no querer debuguear apargarlo.		
				if(logger.isLoggable(LoggerADP.DEBUG_LEVEL)){
					logger.log(LoggerADP.DEBUG_LEVEL,"Save historic flow ->");
					logger.log(LoggerADP.DEBUG_LEVEL,adpFlowTree.toString());
				}
				FlowHistoricManager.getInstance().addFlow(adpFlowTree);
			}
			
			return message;
		}
	}

}
